/////////////////////////////////////////////////////////////////////////////////////
// Include Files
#include "Objects\Galleon.h"

// HACK: raising events in CGame
#include "Main\Game.h"

// managers
#include "Managers\MeshManager.h"

// rendering
#include "Rendering\RenderState.h"

#include <math.h>

/////////////////////////////////////////////////////////////////////////////////////
// CGalleon Implementation

CGalleon::CGalleon() : ABCObject()
{
	// create the render state
	m_pRenderState = new CRenderState();
	m_pRenderState->AddRef();

	// mesh
	m_pRenderState->SetMesh(L"Galleon.mesh");

	// shader
	m_pRenderState->SetShader(L"Galleon.cgfx");

	// matrix
	m_pRenderState->SetMatrixParam(L"g_matModelView", PARAM_MAT_MODELVIEW);
	m_pRenderState->SetMatrixParam(L"g_matModelViewProj", PARAM_MAT_MODELVIEWPROJ);

	// transform
	matrix_t matTransform = Matrix();
	matTransform = MatrixMul( MatrixTranslation(0.0f, 12.0f, 0.0f), matTransform );
	matTransform = MatrixMul( MatrixRotationX(CE_PI_DIV_2), matTransform );
	m_pRenderState->SetTransform(matTransform);

	// HACK: raising event in CGame
	CSingleton<CGame>()->RenderStateAdd.Raise(new CRenderStateEventArg(m_pRenderState));

	// no time has passed
	m_fElapsed = 0.0f;

	// get the starting transform TODO: bake into mesh
	m_matTransform          = Matrix();
	matrix_t matRotationX   = MatrixRotationX(CE_PI_DIV_2);
	m_matTransform          = MatrixMul(m_matTransform, matRotationX);
	matrix_t matRotationY   = MatrixRotationY(CE_PI);
	m_matTransform          = MatrixMul(m_matTransform, matRotationY);
	matrix_t matTranslation = MatrixTranslation(0.0f, 11.0f, -3.5f);
	m_matTransform          = MatrixMul(m_matTransform, matTranslation);
}

CGalleon::~CGalleon()
{
	// HACK: raising event in CGame
	CSingleton<CGame>()->RenderStateRemove.Raise(new CRenderStateEventArg(m_pRenderState));
	m_pRenderState->Release();
}

void CGalleon::Update( float_t _fTime )
{
	// increase the elapsed time
	m_fElapsed += _fTime;

	// final transform
	matrix_t matTransform = m_matTransform;

	// rotation
	float_t fRotX         = -cos(m_fElapsed) / 6.0f;
	matrix_t matRotationX = MatrixRotationX(fRotX);
	matTransform          = MatrixMul(matTransform, matRotationX);

	float_t fRotZ         = cos(m_fElapsed * 0.75f) / 22.0f;
	matrix_t matRotationZ = MatrixRotationZ(fRotZ);
	matTransform          = MatrixMul(matTransform, matRotationZ);

	// translation
	float_t fHeight = 0.5f;
	fHeight += sin(m_fElapsed) * 4.0f;
	fHeight += sin(m_fElapsed * 0.75f) * 1.5f;

	matrix_t matTranslation = MatrixTranslation(0.0f, fHeight, 0.0f);
	matTransform            = MatrixMul(matTransform, matTranslation);

	// set the new transform
	m_pRenderState->Lock();
	m_pRenderState->SetTransform(matTransform);
	m_pRenderState->Unlock();
}
